package de.zainodis.kitchengnome.ui;

import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.ListView;
import android.widget.TextView;
import de.zainodis.commons.LogCat;
import de.zainodis.commons.quickaction.ActionItem;
import de.zainodis.commons.quickaction.QuickAction;
import de.zainodis.commons.quickaction.QuickAction.OnActionItemClickListener;
import de.zainodis.commons.utils.StringUtils;
import de.zainodis.commons.utils.Toaster;
import de.zainodis.kitchengnome.R;
import de.zainodis.kitchengnome.domainmodel.ItemList;
import de.zainodis.kitchengnome.domainmodel.ListItem;
import de.zainodis.kitchengnome.domainmodel.ListType;
import de.zainodis.kitchengnome.ui.adapter.ItemListAdapter;

/**
 * Displays {@link ListItem}s.
 * 
 * @author fzarrai
 * 
 */
public abstract class ItemListDialog extends BaseActivity {

	private static final String TAG = "FoodItemDisplay";

	/** Adapter handling the list items */
	private ItemListAdapter adapter;

	/** Contains quick actions to modify items */
	private QuickAction quickActionBar;

	/** Quick action to delete an item */
	private final int ID_DELETE_ITEM = 0;
	/** Quick action to edit an item (opens editor) */
	private final int ID_EDIT_ITEM = 1;

	/** Position of the item the user last clicked-on */
	private int selectListRow;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Load last edited list...
		LogCat.i(TAG, "Loading last edited item list...");
		ItemList list = getItemListDao().getLastSaved(getListType(), getHelper());
		if (list == null) {
			// ... and if there is none, create a new one
			list = new ItemList(getListType());
			// ... and persist it, so we have a database id
			getItemListDao().save(list, getHelper());
		}

		// Base view for this activity
		setContentView(R.layout.layout_item_editor);

		// Grab the list ...
		ListView listView = (ListView) findViewById(R.id.layout_item_editor_list);
		adapter = new ItemListAdapter(this, list);
		// ... so we can attach the adapter to it
		listView.setAdapter(adapter);
		// Handle clicks on list items
		listView.setOnItemClickListener(getOnItemClickListener());

		listView.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
				LogCat.i(TAG, "Toggled done state for item " + position);
				// Switch the done state of the item and resort
				((ListItem) adapter.getItem(position)).toggleDone();
				// Save the changes immediately
				saveList();
				adapter.sort();
				return true;
			}
		});

		quickActionBar = createActionBar();

	}

	@Override
	protected void onResume() {
		super.onResume();
		// Set suggestions
		AutoCompleteTextView inputBar = (AutoCompleteTextView) findViewById(R.id.layout_inputbar_name);
		// After typing one character suggestions are shown
		inputBar.setThreshold(1);
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line,
				getSuggestionDao().getStringSuggestions());
		inputBar.setAdapter(adapter);
		adapter.notifyDataSetChanged();
	}

	@Override
	protected void onPause() {
		super.onPause();
		// Backup the list
		saveList();
	}

	/**
	 * Called when the user adds a new item. Adds the new item to the list and
	 * persists it to the database, provided that the name is not an empty string
	 * (empty Strings are not added as items).
	 * 
	 * @param view
	 *           the view which caused the add (a button for instance).
	 */
	public void add(View view) {
		// User added a new item to the list
		TextView nameField = (TextView) findViewById(R.id.layout_inputbar_name);
		String name = nameField.getText().toString();
		if (!name.equals(StringUtils.EMPTY)) {
			add(name);
			// Clear the input field
			UiUtils.clearTextView(nameField);
		} else {
			// Notify the user that only non-empty items may be added
			Toaster.shortToast(getString(R.string.name_required), this);
		}
	}

	protected void add(String name) {
		ListItem newEntry = new ListItem(name, adapter.getListId());
		// Add the newly created entry
		adapter.add(newEntry);
		// Persist new entry to the database
		saveList();

		LogCat.i(TAG, "Added new item to the list: " + newEntry.getName());
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == ID_EDIT_ITEM && resultCode == RESULT_OK) {
			// Reload item list (editor already persisted changes
			adapter.update(getItemListDao().getList(adapter.getListId(), getHelper()));
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	/**
	 * Subclasses may override this to decide what should happen if the user
	 * clicks
	 * 
	 * @return
	 */
	protected OnItemClickListener getOnItemClickListener() {
		return new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				selectListRow = position;
				quickActionBar.show(view);
			}
		};
	}

	protected QuickAction createActionBar() {
		QuickAction quickBar = new QuickAction(this);
		quickBar.addActionItem(new ActionItem(ID_DELETE_ITEM, getString(R.string.delete), getResources().getDrawable(
				R.drawable.delete)));
		quickBar.addActionItem(new ActionItem(ID_EDIT_ITEM, getString(R.string.edit), getResources().getDrawable(
				R.drawable.pencil)));

		// Setup QuickAction Bar
		quickBar.setOnActionItemClickListener(new OnActionItemClickListener() {
			@Override
			public void onItemClick(QuickAction source, int pos, int actionId) {
				switch (actionId) {
					case ID_EDIT_ITEM:
						// Create a new edit dialog
						Intent intent = new Intent(ItemListDialog.this, FoodItemEditor.class);
						intent.putExtra(ListItem.TYPE_NAME, (ListItem) adapter.getItem(selectListRow));
						startActivityForResult(intent, ID_EDIT_ITEM);
						break;
					case ID_DELETE_ITEM:
						getListEntryDao().deleteItem(adapter.delete(selectListRow));
						break;
				}
			}
		});
		return quickBar;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.itemlist_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case R.id.clear_all:
				// Deletes all entries from the list
				getListEntryDao().deleteItems(adapter.getList());
				adapter.clearList();
				saveList();
				return true;
			case R.id.clear_done:
				// Deletes all completed entries
				getListEntryDao().deleteDone(adapter.getList());
				adapter.clearDone();
				saveList();
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}

	/**
	 * @return the {@link ListType} being displayed in this dialog.
	 */
	protected abstract ListType getListType();

	/**
	 * Saves the current state of the list backing the adapter.
	 */
	protected void saveList() {
		// Save list to database to update last-saved
		getItemListDao().save(adapter.getList(), getHelper());
	}
}
